# -*- coding:utf-8 -*-

# @File     :models
# @Author   :Yupeng
# @Date     :2018/10/25 19:21
""""
explain:
"""

from enum import IntEnum

from django.utils.encoding import force_text
from django.utils.translation import ugettext_lazy as _


class HTEError(IntEnum):
    """"
    错误枚举类
    """
    SUCCESS = 0
    UNKNOWN_ERROR = 500
    BAD_REQUEST = 400
    PERMISSION_DENIED = 403
    METHOD_NOT_ALLOWED = 405
    UNAUTHORIZED = 401
    NOT_FOUND = 404

    BAD_TOKEN = 2002
    USER_NOT_FOUND = 2003
    WRONG_PASSWORD = 2004
    USER_ALREADY_EXISTS = 2005
    EMAIL_ALREADY_EXISTS = 2006
    BAD_EMAIL = 2007

    EMAIL_NOT_VERIFIED = 2008
    EMAIL_ALREADY_VERIFIED = 2009
    EMAIL_SENDING_FAILED = 2010

    BAD_USERNAME = 2011
    WRONG_CAPTCHA = 2012
    WRONG_FORMULA = 2013

    BAD_DATA = 2102

    FIELD_MISSING = 2200
    WRONG_FIELD_TYPE = 2201
    NOT_ACCEPTABLE = 2202
    NOT_UNIQUE = 2203
    INVALID_FIELD_VALUE = 2204
    BAD_QUERY_SYNTAX = 2205
    BAD_CONDITION = 2206

    PROJECT_ALREADY_EXISTS = 2300
    TOO_MANY_PICTURES = 2301
    CLASS_ASSET_NOT_FOUND = 2302
    VR_TASK_NOT_FOUND = 2303
    PICTURE_REPEATED = 2304
    ASSET_NOT_FOUND = 2305
    CLASS_ASSET_REPEATED = 2306
    PICTURE_NOT_FOUND = 2307
    CAN_NOT_BE_DELETED = 2308
    BAD_PRESSED_ARCHIVE = 2309
    VR_MODEL_NOT_FOUND = 2310
    PICTURE_IS_USED = 2311
    CAN_NOT_BE_MODIFIED = 2312
    NO_TRAIN_CLASS = 2313
    CLASS_HAS_NOT_IMAGE = 2314
    BAD_FILE_TYPE = 2315
    DO_NOT_HAVE_ANY_MODEL = 2316

    def to_dict(self):
        d = {'msg': self.error_message,
             'code': self.value}
        if self.error_detail:
            if isinstance(self.error_detail, str):
                d['extra'] = {'err_detail': self.error_detail}
            elif isinstance(self.error_detail, dict):
                d['extra'] = self.error_detail
        return d

    @property
    def error_message(self):
        return force_text(ERROR_MESSAGE[self][0])

    @property
    def status_code(self):
        return ERROR_MESSAGE[self][1]

    def __call__(self, error_detail):
        self.error_detail = error_detail
        return self

    def __init__(self, *args, **kwargs):
        IntEnum.__init__(self)
        self.error_detail = ''


ERROR_MESSAGE = {
    HTEError.USER_NOT_FOUND: (_('User not found'), 401),
    HTEError.WRONG_PASSWORD: (_('Wrong password'), 401),
    HTEError.USER_ALREADY_EXISTS: (_("Username already exists."), 403),
    HTEError.PERMISSION_DENIED: (_("Permission denied"), 403),
    HTEError.NOT_FOUND: (_('Not found'), 404),
    HTEError.METHOD_NOT_ALLOWED: (_("Method not allowed"), 405),
    HTEError.UNAUTHORIZED: (_("Unauthorized"), 401),
    HTEError.FIELD_MISSING: (_("Field missing"), 422),
    HTEError.WRONG_FIELD_TYPE: (_('Wrong field type'), 422),
    HTEError.NOT_ACCEPTABLE: (_("Wrong content-type(JSON required)"), 406),
    HTEError.UNKNOWN_ERROR: (_("Internal server error. Please contact admin or try again later."), 500),
    HTEError.BAD_TOKEN: (_("Invalid token"), 401),
    HTEError.BAD_DATA: (_("Bad data"), 422),
    HTEError.BAD_EMAIL: (_("Invalid email address"), 422),
    HTEError.EMAIL_ALREADY_EXISTS: (_("Email address already exists"), 422),
    HTEError.EMAIL_ALREADY_VERIFIED: (_("Email address already verified"), 422),
    HTEError.EMAIL_SENDING_FAILED: (_("Email sent failed"), 422),
    HTEError.EMAIL_NOT_VERIFIED: (_("Email address not verified. Please contact admin"), 403),
    HTEError.BAD_USERNAME: (_("Invalid username"), 422),
    HTEError.WRONG_CAPTCHA: (_("Wrong captcha"), 422),
    HTEError.WRONG_FORMULA: (_("Wrong formula,input again"), 422),
    HTEError.PROJECT_ALREADY_EXISTS: (_('The name of the project already exists.'), 422),
    # HTEError.BAD_DATA: (_('Bad data.'), 422),
    HTEError.TOO_MANY_PICTURES: (_('Too many pictures.'), 422),
    HTEError.CLASS_ASSET_NOT_FOUND: (_('This class_asset is not found.'), 422),
    HTEError.VR_TASK_NOT_FOUND: (_('Visual recognition task is not found'), 422),
    HTEError.PICTURE_REPEATED: (_('This picture has been added before.'), 422),
    HTEError.ASSET_NOT_FOUND: (_('This picture does not exist.'), 422),
    HTEError.CLASS_ASSET_REPEATED: (_('The name of the class_asset already exist.'), 422),
    HTEError.PICTURE_NOT_FOUND: (_('The picture of this ID is not found.'), 422),
    HTEError.CAN_NOT_BE_DELETED: (_('This is a test and it can not be deleted.'), 422),
    HTEError.BAD_PRESSED_ARCHIVE: (_('This pressed archive does not meet the requirement. '), 422),
    HTEError.VR_MODEL_NOT_FOUND: (_('This visual recognition model is not found.'), 422),
    HTEError.PICTURE_IS_USED: (_('This picture is used now, so it can not be deleted.'), 422),
    HTEError.CAN_NOT_BE_MODIFIED: (_('Test class can not be modified.'), 422),
    HTEError.NO_TRAIN_CLASS: (_('There is not any class and the task can not begin.'), 422),
    HTEError.CLASS_HAS_NOT_IMAGE: (_('There is not any pictures in some classes.'), 422),
    HTEError.BAD_FILE_TYPE: (_('The file type with some files do not meet the requirements.'), 422),
    HTEError.DO_NOT_HAVE_ANY_MODEL: (_('You do not have any model.'), 422)
}


class HTEException(Exception):
    def __init__(self, hte_error: HTEError, is_api=True):
        self.hte_error = hte_error
        self.is_api = is_api
        if self.hte_error.error_detail:
            self.message = f'{self.hte_error.error_message}:{self.hte_error.error_detail}'
        else:
            self.message = self.hte_error.error_message

    def __repr__(self):
        return self.message

    def __str__(self):
        return self.message

    def __unicode__(self):
        return self.message
